<?php
/**
 * Erstellt und verwaltet Kategoriestrukturierungen
 *
 * @author		Joachim Ruf
 * @copyright	Copyright (c) 2003-2010 Loresoft Software (http://www.loresoft.de)
 *
 * */


Class Yapary_Page_StructureList
{
    /** @var $oSql Yapary_Database_Sql */
    private $oSql           = NULL;
    /** @var $dbTableName string */
    private $dbTableName    = 'yapary_page_structure';


    /**
     * @param Object $_oSql	: Datenbankklasse fuer Datenbankzugriff
     * */
    function __construct (Yapary_Db_Sql_Connector $_oSql)
    {
		if (!$_oSql->database()->table($this->dbTableName)->exists()) {
            $e = new Exception();
            $arrTrace = $e->getTrace();
            $trace = '<b>'.$arrTrace[0]['class'].$arrTrace[0]['type'].$arrTrace[0]['function'].'</b> in <b>'.$arrTrace[0]['file'].'</b> on line <b>'.$arrTrace[0]['line'].'</b>';
            trigger_error('<pre></b>No database installed<br />'.$trace.'</pre>', E_USER_WARNING);
		}

		$this->oSql  = $_oSql;
    }


    /**
     * Fuegt einen neuen Datensatz hinzu
     * @return Yapary_Page_Structure|NULL
     * */
    public function add ($_name1, $_name2 = '', $_name3 = '', $_name4 = '', $_name5 = '')
    {
        $oDbResult = $this->oSql->request('INSERT INTO '.$this->dbTableName.'(Name1, Name2, Name3, Name4, Name5) VALUES (:name1, :name2, :name3, :name4, :name5)',
                                 array('name1' => $_name1,
                                       'name2' => $_name2,
                                       'name3' => $_name3,
                                       'name4' => $_name4,
                                       'name5' => $_name5));

        $lastId = mysql_insert_id();
        $prio = count($this->getListCurrent($lastId));
        $oStructure = new Yapary_Page_Structure($this->oSql, $lastId);
        $oStructure->setOrder($prio);
        $oStructure->save();
        return $oStructure;
    }


    /**
     * Fuegt einen neuen Datensatz dem Elternelement hinzu
     * Wird die Id=0 benutzt, so wird ein Haupteintrag erstellt
     * @param int $_parentId	: Id des Elternelements
     * @param string $_name		: Name des Kindelements
     * @return Yapary_Page_Structure|NULL
     * */
    public function addChild ($_parentId, $_name)
    {
        if ($_parentId == 0) {
            return $this->add($_name);
        }

        $grade     = $this->getGrade($_parentId);
        $oStructure = $this->get($_parentId);

        if ($grade > 5) {
            return NULL;
        }

        // default setzen
        $name1 = $oStructure->getName1();
        $name2 = $oStructure->getName2();
        $name3 = $oStructure->getName3();
        $name4 = $oStructure->getName4();
        $name5 = $oStructure->getName5();

        // Child-Eintrag ueberschreiben
        $name = 'name'.($grade+1);
        $$name = $_name;

//        if ($this->exists($name1, $name2, $name3, $name4, $name5)) {
//            return false;
//        }

        return $this->add($name1, $name2, $name3, $name4, $name5);
    }


    /**
     * Loescht einen existierenden Datensatz
     * @return bool
     * */
    public function delete ($_id)
    {
        $i = 0;
        $arr = $this->getListCurrent($_id);
        $count = count($arr);
        $oDbResult = $this->oSql->request('DELETE
                					    FROM '.$this->dbTableName.'
                					    WHERE Id=:id',
                                      array('id' => $_id));

        if ($count >= 1) {
            while (list(,$class) = each($arr)) {
                if ($class->getId() != $_id) {
                    $class->setOrder($i++);
                    $class->save();
                }
            }
        }

        return true;
    }


    /**
     * Loescht einen Datensatz aus dem Elternelement
     * @param int $_parentId	: Id des Elternelements
     * @param string $_name		: Name des Kindelements
     * @return bool
     * */
    public function deleteChild ($_parentId, $_name)
    {
        $grade   = $this->getGrade($_parentId);
        $arrList = $this->getListChild($_parentId);
        $count   = count($arrList);

        if ($grade > 5) {
            return false;
        }

        if ($count) {
            while (list(,$class) = each($arrList)) {
                /* @var $class Yapary_Page_Structure */
                $name = 'getName'.($grade+1);
                if ($class->$name() == $_name) {
                    return $this->delete($class->getId());
                }
            }
        }

        return false;
    }


    /**
     * Benennt einen vorhandenen Unterseiteneintrag aus dem Elternelement um
     * @param int $_parentId	: Id des Elternelements
     * @param string $_name		: Name des Kindelements
     * @return bool
     * */
    public function renameChild ($_parentId, $_nameOld, $_nameNew)
    {
        $grade   = $this->getGrade($_parentId);
        $arrList = $this->getListChild($_parentId);
        $count   = count($arrList);

        if ($grade > 5) {
            return false;
        }

        if ($count) {
            while (list(,$class) = each($arrList)) {
                /* @var $class Yapary_Page_Structure */
                $name = 'getName'.($grade+1);
                if ($class->$name() == $_nameOld) {
                    return $this->rename($class->getId(), $_nameNew);
                }
            }
        }

        return false;
    }


    /**
     * Benennt einen vorhandenen Eintrag um
     * @param int $_parentId	: Id des Elternelements
     * @param string $_name		: Name des Kindelements
     * @return bool
     * */
    public function rename ($_id, $_name)
    {
        $grade   = $this->getGrade($_id);
        $oStructure = $this->get($_id);

        if ($oStructure == NULL) {
            return false;
        }
        if ($grade > 5) {
            return false;
        }
        if ($grade < 0) {
            return false;
        }

        for ($i=1; $i<=$grade; $i++) {
            $name = 'Name'.($i);
            $oldName = 'get'.$name;
            $oldName = $oStructure->$oldName();

            $arrWhereClause[] = $name."='".$oldName."'";
        }
        $whereClause = implode(' AND ', $arrWhereClause);

        $name = 'Name'.($grade);
        $oDbResult = $this->oSql->request('UPDATE '.$this->dbTableName.'
                					 SET '.$name.'=:newName
                					 WHERE '.$whereClause,
                                    array('newName' => $_name));
        return true;
    }


    /**
     * Liefert einen Datensatz anhand der Id
     * @return Yapary_Page_Structure
     * */
    public function get ($_id)
    {
        $oDbResult = $this->oSql->request('SELECT *
        					  FROM '.$this->dbTableName.' t1
        					  WHERE Id=:id',
                            array('id' => $_id));

        if ($oDbResult->getCount() == 1) {
            $row = $oDbResult->getNext();
            return new Yapary_Page_Structure($this->oSql, $row);
        }

        return NULL;
    }


    /**
     * Liefert die Ebende als im Format Name1/Name2/Name3/.. als String
     * @param int $_id			: Id des Elements
     * @param string $_delimiter: Trennsymbol, welches zwischen den Eintraegen eingefuegt werden soll
     * @param int $startIndex	: {1,5} Index, mit welchem begonnen werden soll
     * @return string
     * */
    public function getLayer ($_id, $_delimiter = '/', $startIndex = 1) {
        $arrResult = array();
        $i = 0;

        if (!is_numeric($_id)) {
            return NULL;
        }

        $oDbResult = $this->oSql->request('SELECT *
        					  FROM '.$this->dbTableName.' t1
        					  WHERE Id=:id',
                            array('id' => $_id));


        if ($oDbResult->getCount() >= 1) {
            $row = $oDbResult->getNext();
            for ($i=$startIndex; $i<=5; $i++) {
                $name = 'Name'.$i;

                if ($row->$name != '' && $i>=1 && $i >= $startIndex) {
                    $arrResult[] = $row->$name;
                }
            }
        }

        return implode($_delimiter, $arrResult);
    }


    /**
     * Liefert alle Datensaetz der 1.Kategorie
     * @return Array[Yapary_Page_Structure]
     * */
    public function getList1 ($_orderBy = 'AscOrder')
    {
        $arrResult = array();
        $_orderBy = (preg_match('/^([a-zA-Z-_ ]+)([a-zA-Z-_0-9 ]*)$/', $_orderBy)) ? ' ORDER BY '.$_orderBy : '';

        $oDbResult = $this->oSql->request('SELECT *
        					  FROM '.$this->dbTableName.' t1
        					  WHERE Name2=""
        					  '.$_orderBy.'',
                            array());

        if ($oDbResult->getCount() >= 1) {
            while ($row = $oDbResult->getNext()) {
                $arrResult[] = new Yapary_Page_Structure($this->oSql, $row);
            }
        }

        return $arrResult;
    }


    /**
     * Liefert alle Datensaetz der 2.Kategorie
     * @return Array[Yapary_Page_Structure]
     * */
    public function getList2 ($_name1, $_orderBy = 'AscOrder')
    {
        $arrResult = array();
        $_orderBy = (preg_match('/^([a-zA-Z-_ ]+)([a-zA-Z-_0-9 ]*)$/', $_orderBy)) ? ' ORDER BY '.$_orderBy : '';

        $oDbResult = $this->oSql->request('SELECT *
        					  FROM '.$this->dbTableName.' t1
        					  WHERE Name1=:name1 AND
        					  		Name2!="" AND
        					  		Name3=""
        					  '.$_orderBy.'',
                            array('name1' => $_name1));

        if ($oDbResult->getCount() >= 1) {
            while ($row = $oDbResult->getNext()) {
                $arrResult[] = new Yapary_Page_Structure($this->oSql, $row);
            }
        }

        return $arrResult;
    }


    /**
     * Liefert alle Datensaetz der 3.Kategorie
     * @return Array[Yapary_Page_Structure]
     * */
    public function getList3 ($_name1, $_name2, $_orderBy = 'AscOrder')
    {
        $arrResult = array();
        $_orderBy = (preg_match('/^([a-zA-Z-_ ]+)([a-zA-Z-_0-9 ]*)$/', $_orderBy)) ? ' ORDER BY '.$_orderBy : '';

        $oDbResult = $this->oSql->request('SELECT *
        					  FROM '.$this->dbTableName.' t1
        					  WHERE Name1=:name1 AND
        					  		Name2=:name2 AND
        					  		Name3!="" AND
        					  		Name4=""
        					  '.$_orderBy.'',
                            array('name1' => $_name1,
                                  'name2' => $_name2));

        if ($oDbResult->getCount() >= 1) {
            while ($row = $oDbResult->getNext()) {
                $arrResult[] = new Yapary_Page_Structure($this->oSql, $row);
            }
        }

        return $arrResult;
    }


    /**
     * Liefert alle Datensaetz der 4.Kategorie
     * @return Array[Yapary_Page_Structure]
     * */
    public function getList4 ($_name1, $_name2, $_name3, $_orderBy = 'AscOrder')
    {
        $arrResult = array();
        $_orderBy = (preg_match('/^([a-zA-Z-_ ]+)([a-zA-Z-_0-9 ]*)$/', $_orderBy)) ? ' ORDER BY '.$_orderBy : '';

        $oDbResult = $this->oSql->request('SELECT *
        					  FROM '.$this->dbTableName.' t1
        					  WHERE Name1=:name1 AND
        					  		Name2=:name2 AND
        					  		Name3=:name3 AND
        					  		Name4!="" AND
        					  		Name5=""
        					  '.$_orderBy.'',
                            array('name1' => $_name1,
                                  'name2' => $_name2,
                                  'name3' => $_name3));

        if ($oDbResult->getCount() >= 1) {
            while ($row = $oDbResult->getNext()) {
                $arrResult[] = new Yapary_Page_Structure($this->oSql, $row);
            }
        }

        return $arrResult;
    }


    /**
     * Liefert alle Datensaetz der 5.Kategorie
     * @return Array[Yapary_Page_Structure]
     * */
    public function getList5 ($_name1, $_name2, $_name3, $_name4, $_orderBy = 'AscOrder')
    {
        $arrResult = array();
        $_orderBy = (preg_match('/^([a-zA-Z-_ ]+)([a-zA-Z-_0-9 ]*)$/', $_orderBy)) ? ' ORDER BY '.$_orderBy : '';

        $oDbResult = $this->oSql->request('SELECT *
        					  FROM '.$this->dbTableName.' t1
        					  WHERE Name1=:name1 AND
        					  		Name2=:name2 AND
        					  		Name3=:name3 AND
        					  		Name4=:name4 AND
        					  		Name5!=""
        					  '.$_orderBy.'',
                            array('name1' => $_name1,
                                  'name2' => $_name2,
                                  'name3' => $_name3,
                                  'name4' => $_name4));

        if ($oDbResult->getCount() >= 1) {
            while ($row = $oDbResult->getNext()) {
                $arrResult[] = new Yapary_Page_Structure($this->oSql, $row);
            }
        }

        return $arrResult;
    }


    /**
     * Liefert einen Datensatz anhand der Id
     * @return int
     * */
    public function getGrade ($_id)
    {
        $oDbResult = $this->oSql->request('SELECT *
        					  FROM '.$this->dbTableName.' t1
        					  WHERE Id=:id',
                            array('id' => $_id));

        if ($oDbResult->getCount() == 1) {
            $row = $oDbResult->getNext();
            for ($i=1; $i<=5; $i++) {
                $name = 'Name'.$i;
                if ($row->$name == '') {
                    return $i-1;
                }
            }
            return 5;
        }

        return 0;
    }


    /**
     * Hilfsfunktion: Liefert alle Datensaetz anhand der Id und des Kategoriegrads
     * @return Array[Yapary_Page_Structure]
     * */
    private function getListByGrade ($_id, $_grade, $_orderBy = 'AscOrder')
    {
        $arrResult = array();

        $oStructure = new Yapary_Page_Structure($this->oSql, $_id);
        switch ($_grade) {
            case 1:
                $arrResult = $this->getList1($_orderBy);
                break;
            case 2:
                $arrResult = $this->getList2($oStructure->getName1(), $_orderBy);
                break;
            case 3:
                $arrResult = $this->getList3($oStructure->getName1(), $oStructure->getName2(), $_orderBy);
                break;
            case 4:
                $arrResult = $this->getList4($oStructure->getName1(), $oStructure->getName2(), $oStructure->getName3(), $_orderBy);
                break;
            case 5:
                $arrResult = $this->getList5($oStructure->getName1(), $oStructure->getName2(), $oStructure->getName3(), $oStructure->getName4(), $_orderBy);
                break;
        };


        return $arrResult;
    }


    /**
     * Liefert alle Child-Datensaetz anhand der Id
     * @return Array[Yapary_Page_Structure]
     * */
    public function getListChild ($_id, $_orderBy = 'AscOrder')
    {
        $arrResult = array();

        $grade = $this->getGrade($_id)+1;
        if ($grade == 0 || $grade > 5) {
            return $arrResult;
        }

        return $this->getListByGrade($_id, $grade, $_orderBy);
    }


    /**
     * Liefert den Parent-Datensaetz anhand der Id
     * @return Array[Yapary_Page_Structure]
     * */
    public function getListParent ($_id, $_orderBy = 'AscOrder')
    {
        $arrResult = array();

        $grade = $this->getGrade($_id)-1;
        if ($grade == 0 || $grade > 5) {
            return $arrResult;
        }

        return $this->getListByGrade($_id, $grade, $_orderBy);
    }


    /**
     * Liefert den Parent-Datensaetz anhand der Id
     * @return Array[Yapary_Page_Structure]
     * */
    public function getListCurrent ($_id, $_orderBy = 'AscOrder')
    {
        $arrResult = array();

        $grade = $this->getGrade($_id);
        if ($grade == 0 || $grade > 5) {
            return $arrResult;
        }

        return $this->getListByGrade($_id, $grade, $_orderBy);
    }


    /**
     * Erhoeht die AscOrderritaet um 1
     * @return bool
     * */
    public function setOrderUp ($_id)
    {
        $arr = $this->getListCurrent($_id);
        $count = count($arr);
        if ($count > 1) {
            $objA = NULL;
            $objB = NULL;
            while (list(, $class) = each($arr)) {
                /*@var $class Yapary_Page_Structure*/
                $objA = $objB;
                $objB = $class;

                if ($objB->getId() == $_id && is_object($objA)) {
                    $prioA = $objA->getOrder();
                    $prioB = $objB->getOrder();

                    $objA->setOrder($prioB);
                    $objB->setOrder($prioA);
                    if ($objA->save() && $objB->save()) {
                        return true;
                    }
                }
            }
        }

        return false;
    }


    /**
     * Erniedrigt die AscOrderritaet um 1
     * @return bool
     * */
    public function setOrderDown ($_id)
    {
        $arr = $this->getListCurrent($_id);
        $count = count($arr);
        if ($count > 1) {
            $objA = NULL;
            $objB = NULL;
            for ($i=0; $i<$count; $i++) {
                $objA = $arr[$i];

                if ($objA->getId() == $_id) {
                    if ($i+1 != $count) { // Wenn Id nicht das letzte Element, dann tausche mit naechstem Element
                        $objB = $arr[$i+1];

                        $prioA = $objA->getOrder();
                        $prioB = $objB->getOrder();

                        $objA->setOrder($prioB);
                        $objB->setOrder($prioA);
                        if ($objA->save() && $objB->save()) {
                            return true;
                        }
                    }
                }
            }
        }

        return false;
    }


    /**
     * Fuegt einen neuen Datensatz hinzu
     * @return Yapary_Page_Structure|NULL
     * */
    public function exists ($_name1, $_name2 = '', $_name3 = '', $_name4 = '', $_name5 = '')
    {
        $oDbResult = $this->oSql->request('SELECT Id
    						  FROM '.$this->dbTableName.'
    						  WHERE
    						  	Name1=:name1 AND
    						  	Name2=:name2 AND
    						  	Name3=:name3 AND
    						  	Name4=:name4 AND
    						  	Name5=:name5',
                             array('name1' => $_name1,
                                   'name2' => $_name2,
                                   'name3' => $_name3,
                                   'name4' => $_name4,
                                   'name5' => $_name5));

        if ($oDbResult->getCount() == 1) {
            return true;
        }

        return false;
    }


}


?>